package com.wocai.jrt.orgadmin.stats.service.impl;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.wocai.jrt.admin.common.cache.Const;
import com.wocai.jrt.orgadmin.appointment.dao.AppointmentDao;
import com.wocai.jrt.orgadmin.appointment.model.Appointment;
import com.wocai.jrt.orgadmin.investor.bean.InvestorReqBean;
import com.wocai.jrt.orgadmin.investor.dao.InvestorDao;
import com.wocai.jrt.orgadmin.investor.model.Investor;
import com.wocai.jrt.orgadmin.orders.bean.OrderReqBean;
import com.wocai.jrt.orgadmin.orders.dao.OrdersDao;
import com.wocai.jrt.orgadmin.orders.model.Orders;
import com.wocai.jrt.orgadmin.stats.bean.InvestorCountBean;
import com.wocai.jrt.orgadmin.stats.bean.PerFormReqBean;
import com.wocai.jrt.orgadmin.stats.bean.SortClass;
import com.wocai.jrt.orgadmin.stats.service.spi.PerformanceStatsService;
import com.wocai.jrt.orgadmin.stats.service.spi.RedisCacheService;
import com.wocai.jrt.orgadmin.utils.MyDateUtils;
import com.wocai.jrt.orgadmin.utils.UserUtils;

/**
 * 业绩统计控制器
 * @author zhangyz
 * @date 2015年9月22日09:19:19
 */
@Named
public class PerformanceStatsServiceImpl  implements PerformanceStatsService{
	private static final Logger LOGGER = LoggerFactory.getLogger(PerformanceStatsServiceImpl.class);
	@Inject
	private InvestorDao investorDao;
	@Inject
	private AppointmentDao appointmentDao;
	@Inject
	private OrdersDao ordersDao;
	@Inject
    private RedisCacheService redisCacheServiceImpl;
	 
	/**
     * 直接从数据库中获取业绩数据并统计
     * @param model 参数
     */
	@Override
	public Map<String, Object> performanceStatsFromDB(PerFormReqBean model) {
		Map<String, Object> mapsMap = new HashMap<String, Object>();
		SimpleDateFormat sdFormat = new SimpleDateFormat(model.getFormatStr());
		Map<String, Double> ordersMap = new HashMap<String, Double>();
		Map<String, Integer> investorMap = new HashMap<String, Integer>();
		Map<String, Integer> appointmentMap = new HashMap<String, Integer>();
		
		 //线下订单、支付流水统计销售额
		OrderReqBean orders = new OrderReqBean();
		Date dateEnd = model.getEndTime();
		Date dateStart = model.getStartTime();
		orders.setPayTimeEnd(dateEnd);
		orders.setPayTimeStart(dateStart);
		orders.setOrgId(model.getOrgId());
		List<InvestorCountBean> ordersCountList = new ArrayList<InvestorCountBean>();
		NumberFormat nf = new DecimalFormat("####.##");
		try {
			List<Orders> ordersList = ordersDao.orderStats(orders);
			String dateString = "";
			//按统计周期初始化map, 给出的日期开始日比终了日大则不执行
			if(!model.getFormatStr().equals("yyyy")){
				 if (dateStart.compareTo(dateEnd) >= 0) {
					  return null;
				  }
				  Date currentPrintDay = dateStart;
					   // 日期加一后判断是否达截止日
					   //DateUtils.isSameDay(currentPrintDay, dateEnd);
					   while (!currentPrintDay.after(dateEnd)) {
						   ordersMap.put(sdFormat.format(currentPrintDay),  0D);
						   investorMap.put(sdFormat.format(currentPrintDay),  0);
						   appointmentMap.put(sdFormat.format(currentPrintDay),  0);
						   // 日期加一
						   currentPrintDay.setTime(currentPrintDay.getTime()+3600*24*1000);
					  }
			}
			 
			//销售额统计
			for (int i = 0; i < ordersList.size(); i++) {
				Date regist = ordersList.get(i).getPayTime();
				Double salesDouble = ordersList.get(i).getOrderAmount();
				if(salesDouble == null){
					salesDouble = 0D;
				}
				if(regist != null){
					dateString = sdFormat.format(regist);
					if (ordersMap.containsKey(dateString)) {
						ordersMap.put(dateString, Double.parseDouble(nf.format(ordersMap.get(dateString)+salesDouble)));
					} else {
						ordersMap.put(dateString,  Double.parseDouble(nf.format(salesDouble)));
					}
				}
			}
			transMap2Bean(ordersMap,ordersCountList);
		} catch (Exception e) {
			LOGGER.error("PerformanceStats for orders  error, msg=[{}]",e.getMessage());
		}
		 //投资人统计
		InvestorReqBean reqBean = new InvestorReqBean();
		reqBean.setStartTime(model.getStartTime());
		reqBean.setEndTime(model.getEndTime());
		reqBean.setOrgId(model.getOrgId());
		List<InvestorCountBean> invesCountList = new ArrayList<InvestorCountBean>();
		try {
			List<Investor> invesList = investorDao.queryFactor(reqBean);
			String dateString = "";
			for (int i = 0; i < invesList.size(); i++) {
				Date regist = invesList.get(i).getRegisterTime();
				if(regist != null){
					dateString = sdFormat.format(regist);
					if (investorMap.containsKey(dateString)) {
						investorMap.put(dateString, 1 + investorMap.get(dateString));
					} else {
						investorMap.put(dateString, 1);
					}
				}
			}
			transMap2BeanEx(investorMap,invesCountList);
		} catch (Exception e) {
			LOGGER.error("PerformanceStats for investor  error, msg=[{}]",e.getMessage());
		}
		
		 //预约统计
		Appointment appoReq = new Appointment();
		appoReq.setStartTime(model.getStartTime());
		appoReq.setEndTime(model.getEndTime());
		appoReq.setOrgId(model.getOrgId());
		List<InvestorCountBean> allAppoCountlist = new ArrayList<InvestorCountBean>();
		try {
			List<Appointment> appointmentList = appointmentDao.appointmentCount(appoReq);
			String appoString;
			Integer stateInteger;
			Date appointmentDate;
			for (Appointment appointmentResBean : appointmentList) {
				appointmentDate = appointmentResBean.getCreateTime();
				appoString = sdFormat.format(appointmentDate);
				stateInteger = appointmentResBean.getState();
				if(appoString!=null&&stateInteger!=2){
					if (appointmentMap.containsKey(appoString)) {
						appointmentMap.put(appoString, 1 + appointmentMap.get(appoString));
					} else {
						appointmentMap.put(appoString, 1);
					}
				}
			}	
			//所有预约单统计数据封装到bean中
			transMap2BeanEx(appointmentMap,allAppoCountlist);
		} catch (Exception e) {
			LOGGER.error("PerformanceStats for appoinemtent  error, msg=[{}]",e.getMessage());
		}
		mapsMap.put("order", ordersCountList);
		mapsMap.put("investor", invesCountList);
		mapsMap.put("appointment", allAppoCountlist);
		return mapsMap;
	}
	
	
	/**
	 * 将Map转换成JavaBean
	 * @param map
	 * @param list
	 */
	private void transMap2Bean(Map<String, Double> map,List<InvestorCountBean> list) {
		//统计数据封装到bean中
		Iterator<?> it = map.entrySet().iterator();
		while (it.hasNext()) {
			InvestorCountBean bean = new InvestorCountBean();
			Entry<?, ?> entry = (Entry<?, ?>) it.next();
			bean.setSales(Double.parseDouble(entry.getValue().toString()));
			bean.setDate(entry.getKey().toString());
			list.add(bean);
		}
		//统计结果List按时间升序排列
		Collections.sort(list, new SortClass());
	}
	
	/**
	 * 将Map转换成JavaBean扩展
	 * @param map
	 * @param list
	 */
	private void transMap2BeanEx(Map<String, Integer> map,List<InvestorCountBean> list) {
		//统计数据封装到bean中
		Iterator<?> it = map.entrySet().iterator();
		while(it.hasNext()){
			InvestorCountBean tempbean = new InvestorCountBean();
			Entry<?, ?> entry = (Entry<?, ?>)it.next();
			tempbean.setCount(Integer.parseInt(entry.getValue().toString()));
			tempbean.setDate(entry.getKey().toString());
			list.add(tempbean);
		}
		//统计结果List按时间升序排列
		Collections.sort(list, new SortClass());
	}
	
	/**
	 * 从缓存中获取所需要的数据
	 * @return InvestorCountBean
	 */
	  public Map<String, Object> getDemandCache(PerFormReqBean model) {
		    Map<String, Object> mapsMap = new HashMap<String, Object>();
		    String formatStr = model.getFormatStr();
			SimpleDateFormat sdFormat = new SimpleDateFormat(formatStr);
			Map<String, Double> ordersMap = new HashMap<String, Double>();
			Map<String, Integer> investorMap = new HashMap<String, Integer>();
			Map<String, Integer> appointmentMap = new HashMap<String, Integer>();
			String orgId = UserUtils.getOrgId();
			 //订单统计
			Date dateEnd = null;
			Date dateStart = null;
			List<InvestorCountBean> ordersCountList = new ArrayList<InvestorCountBean>();
			List<InvestorCountBean> invesCountList = new ArrayList<InvestorCountBean>();
			List<InvestorCountBean> allAppoCountlist = new ArrayList<InvestorCountBean>();
			try {
				if(!formatStr.equals("yyyy")){
					dateEnd = model.getEndTime();
					dateStart = model.getStartTime();
				}else{
					dateStart = sdFormat.parse(redisCacheServiceImpl.getEarliestYear(Const.PREFIX_PERFORMANCE_EARLIEST_YEAR+orgId));
					dateEnd =new Date();
				}
				//按统计周期初始化map, 给出的日期开始日比终了日大则不执行
				 if (dateStart.compareTo(dateEnd) >= 0) {
					  return null;
				  }
				  Date currentPrintDay = dateStart;
				  while (true) {
					   //日期增加后判断是否达截止日
					   if (!currentPrintDay.after(dateEnd)) {
						   String formatDate = sdFormat.format(currentPrintDay);
						   InvestorCountBean inves = redisCacheServiceImpl.getPerformanceCache(Const.PREFIX_PERFORMANCE_INVESTOR_STATS+orgId+"_"+formatDate);
						   if(inves != null){
							   investorMap.put(sdFormat.format(currentPrintDay),  inves.getCount());
						   }else{
							   investorMap.put(sdFormat.format(currentPrintDay),  0);
						   }
						   
						   InvestorCountBean orders = redisCacheServiceImpl.getPerformanceCache(Const.PREFIX_PERFORMANCE_ORDERS_STATS+orgId+"_"+formatDate);
						   if(orders != null){
							   ordersMap.put(sdFormat.format(currentPrintDay),  orders.getSales());
						   }else{
							   ordersMap.put(sdFormat.format(currentPrintDay),  0D);
						   }
						   
						   InvestorCountBean appointment = redisCacheServiceImpl.getPerformanceCache(Const.PREFIX_PERFORMANCE_APPOINTMENT_STATS+orgId+"_"+formatDate);
						   if(appointment != null){
							   appointmentMap.put(sdFormat.format(currentPrintDay),  appointment.getCount());
						   }else{
							   appointmentMap.put(sdFormat.format(currentPrintDay),  0);
						   }
						   // 日期加一天
						   if(formatStr.equals("yyyy-MM-dd")){
							   currentPrintDay.setTime(currentPrintDay.getTime()+3600*24*1000);   
						   }
						   //日期加一月
						   if(formatStr.equals("yyyy-MM")){
							   currentPrintDay = DateUtils.addMonths(currentPrintDay, 1);
						   }
						   //日期加一年
						   if(formatStr.equals("yyyy")){
							   currentPrintDay = DateUtils.addYears(currentPrintDay, 1);
						   }
					  }else{
						  break;
					  }
				  }
			      //所有销售额统计数据封装到bean中
				  transMap2Bean(ordersMap,ordersCountList);
				  //所有客户新增数量统计数据封装到bean中
				  transMap2BeanEx(investorMap,invesCountList);
				  //所有预约单统计数据封装到bean中
				  transMap2BeanEx(appointmentMap,allAppoCountlist);
			} catch (Exception e) {
				LOGGER.error("PerformanceStats  from Cache error, msg=[{}]",e.getMessage());
			}
			mapsMap.put("order", ordersCountList);
			mapsMap.put("investor", invesCountList);
			mapsMap.put("appointment", allAppoCountlist);
			return mapsMap;
	    }
	  
    /**
     * 计算业绩所有历史数据
     */
    public void preformanceStatsCount(){
    	//获取所有机构列表
		List<String> orgIdList = investorDao.getAllOrgIdList();
		OrderReqBean oReqBean = new OrderReqBean();
		InvestorReqBean invesReqBean = new InvestorReqBean();
		Appointment appoReqBean = new Appointment();
		//为所有机构统计业绩数据
		for (String string : orgIdList) {
			oReqBean.setOrgId(string);
			invesReqBean.setOrgId(string);
			appoReqBean.setOrgId(string);
			List<Orders> ordersList = ordersDao.orderStats(oReqBean);
	    	List<Investor> invesList = investorDao.queryFactor(invesReqBean);
	    	List<Appointment> appointmentList = appointmentDao.appointmentCount(appoReqBean);
	    	String[] str = new String[]{"yyyy","yyyy-MM","yyyy-MM-dd"};
	    	for (int i = 0; i < str.length; i++) {
	    		performanceStatsSaveRedis(str[i],string,ordersList,invesList,appointmentList);
			}
		}
    }
    
	/**
     * 按年、月、日计算所有的业绩历史数据保存到缓存中
     * @param formatString 参数:“yyyy” "yyyy-MM" "yyyy-MM-dd"
     */
	@Override
	public void performanceStatsSaveRedis(String formatString,String orgId,List<Orders> ordersList,List<Investor> invesList,List<Appointment> appointmentList) {
		SimpleDateFormat sdFormat = new SimpleDateFormat(formatString);
		int earliestYear = Integer.parseInt(DateFormatUtils.format(new Date(), "yyyy"));
		 //订单统计
		try {
			Map<String, Double> map = new HashMap<String, Double>();
			NumberFormat nf = new DecimalFormat("###.##");
			String dateString = "";
			//对线下订单进行销售额统计
			for (int i = 0; i < ordersList.size(); i++) {
				Date regist = ordersList.get(i).getPayTime();
				Double salesDouble = ordersList.get(i).getOrderAmount();
				if(salesDouble == null){
					salesDouble = 0D;
				}
				if(regist != null){
					dateString = sdFormat.format(regist);
					Integer integer = new Integer(0);
					if(formatString.equals("yyyy")){
						integer = Integer.parseInt(dateString);
					}
					if(formatString.equals("yyyy") && earliestYear>integer){
						earliestYear = integer;
					}
					if (map.containsKey(dateString)) {
						LOGGER.info("[{}] 的线下订单统计销售额是：[{}]",dateString,Double.parseDouble(nf.format(map.get(dateString)+salesDouble)));
						map.put(dateString, Double.parseDouble(nf.format(map.get(dateString)+salesDouble)));
					} else {
						map.put(dateString, Double.parseDouble(nf.format(salesDouble)));
					}
				}
				//将统计信息保存更新到缓存中
				InvestorCountBean bean = new InvestorCountBean();
				bean.setSales(map.get(dateString));
				bean.setDate(dateString);
				redisCacheServiceImpl.savePerformanceCache(bean,Const.PREFIX_PERFORMANCE_ORDERS_STATS+orgId+"_"+dateString);
			}
		} catch (Exception e) {
			LOGGER.error("PerformanceStats for orders  error, msg=[{}]",e.getMessage());
		}
		 // 投资人统计
		try {
			Map<String, Integer> map = new HashMap<String, Integer>();
			String dateString = "";
			for (int i = 0; i < invesList.size(); i++) {
				Date regist = invesList.get(i).getRegisterTime();
				if(regist != null){
					dateString = sdFormat.format(regist);
					if(formatString.equals("yyyy")){
						Integer integer = Integer.parseInt(dateString);
						if(earliestYear>integer){
							earliestYear = integer;
						}
					}
					if (map.containsKey(dateString)) {
						map.put(dateString, 1 + map.get(dateString));
					} else {
						map.put(dateString, 1);
					}
					InvestorCountBean bean = new InvestorCountBean();
					bean.setCount(map.get(dateString));
					bean.setDate(dateString);
					redisCacheServiceImpl.savePerformanceCache(bean,Const.PREFIX_PERFORMANCE_INVESTOR_STATS+orgId+"_"+dateString);
				}
			}
		} catch (Exception e) {
			LOGGER.error("PerformanceStats for investor  error, msg=[{}]",e.getMessage());
		}
		
		 //预约统计
		try {
			Map<String, Integer> appointmentMap = new HashMap<String, Integer>();
			String appoString;
			Integer stateInteger;
			Date appointmentDate;
			for (Appointment appointmentResBean : appointmentList) {
				appointmentDate = appointmentResBean.getCreateTime();
				appoString = sdFormat.format(appointmentDate);
				if(formatString.equals("yyyy")){
					Integer integer = Integer.parseInt(appoString);
					if(earliestYear>integer){
						earliestYear = integer;
					}
				}
				stateInteger = appointmentResBean.getState();
				if(appoString!=null&&stateInteger!=2){
					if (appointmentMap.containsKey(appoString)) {
						appointmentMap.put(appoString, 1 + appointmentMap.get(appoString));
					} else {
						appointmentMap.put(appoString, 1);
					}
					InvestorCountBean bean = new InvestorCountBean();
					bean.setCount(appointmentMap.get(appoString));
					bean.setDate(appoString);
					redisCacheServiceImpl.savePerformanceCache(bean,Const.PREFIX_PERFORMANCE_APPOINTMENT_STATS+orgId+"_"+appoString);
				}
			}	
		} catch (Exception e) {
			LOGGER.error("PerformanceStats for appoinemtent  error, msg=[{}]",e.getMessage());
		}
		if (formatString.equals("yyyy")) {
			redisCacheServiceImpl.saveEarliestYear(Const.PREFIX_PERFORMANCE_EARLIEST_YEAR+orgId,String.valueOf(earliestYear));
		}
	}
	
	/**
	 * 更新当天、当月、当年业绩统计数据到缓存
	 */
	@Override
	public void updateCurPerformanceStatsRedis(){
		OrderReqBean oReqBean = new OrderReqBean();
		InvestorReqBean invesReqBean = new InvestorReqBean();
		Appointment appoReqBean = new Appointment();
		Date today = new Date();
		String year = DateFormatUtils.format(today, "yyyy");
		String month = DateFormatUtils.format(today, "MM");
		String day = DateFormatUtils.format(today, "dd");
		//获取所有机构列表
		List<String> orgIdList = investorDao.getAllOrgIdList();
		//为所有机构统计业绩数据
		for (String string : orgIdList) {
			oReqBean.setOrgId(string);
			invesReqBean.setOrgId(string);
			appoReqBean.setOrgId(string);
			List<Orders> ordersList = new ArrayList<Orders>() ;
	    	List<Investor> invesList = new ArrayList<Investor>();
	    	List<Appointment> appointmentList = new ArrayList<Appointment>();
	    	String[] str = new String[]{"yyyy","yyyy-MM","yyyy-MM-dd"};
	    	Date startDate = null;
			Date endDate = null;
	    	for (int i = 0; i < str.length; i++) {
	    		if(str[i].equals("yyyy")){
	    			startDate = MyDateUtils.getYearFirst(year);
	    			endDate  = MyDateUtils.getYearLast(year);
	    		}else if(str[i].equals("yyyy-MM")){
	    			startDate = MyDateUtils.getMonthFirst(year,month);
	    			endDate  = MyDateUtils.getMonthLast(year,month);
	    		}else if(str[i].equals("yyyy-MM-dd")){
	    			startDate = MyDateUtils.getDayFirst(year, month,day);
	    			endDate  = MyDateUtils.getDayLast(year,month,day);
	    		}
	    		oReqBean.setPayTimeEnd(endDate);
    			oReqBean.setPayTimeStart(startDate);
    			invesReqBean.setEndTime(endDate);
    			invesReqBean.setStartTime(startDate);
    			appoReqBean.setEndTime(endDate);
    			appoReqBean.setStartTime(startDate);
	    		ordersList = ordersDao.orderStats(oReqBean);
    	    	invesList = investorDao.queryFactor(invesReqBean);
    	    	appointmentList = appointmentDao.appointmentCount(appoReqBean);
	    		performanceStatsSaveRedis(str[i],string,ordersList,invesList,appointmentList);
			}
		}
	}
	
}
